---
title: "Tools"
description: "Invoke server functions from your MCP client"
icon: "wrench"
---

Tools are executable functions that MCP servers expose to clients. They enable your applications to perform actions, retrieve data, and interact with external systems through a standardized interface with type-safe parameters and structured results.

## Understanding Tools

In the MCP protocol, tools represent server capabilities that clients can invoke. Each tool is a well-defined function with:

- **Schema-based validation**: Parameters are validated using JSON Schema
- **Type-safe execution**: Input and output structures are clearly defined
- **Asynchronous operation**: All tool calls support async execution
- **Error handling**: Built-in error reporting and handling

<Tip>
**Common Use Cases**: Tools can perform file operations, make API calls, query databases, execute system commands, process data, and much more. Each MCP server exposes its own set of specialized tools.
</Tip>

## Listing Available Tools

To see what tools are available from a connected MCP server:

<CodeGroup>
```typescript TypeScript
import { MCPClient } from 'mcp-use'

async function listTools() {
    // Initialize client with server configuration
    const config = {
        mcpServers: {
            // Your server definitions here
        }
    }
    const client = new MCPClient(config)

    // Connect to servers
    await client.createAllSessions()

    // Get a session for a specific server
    const session = client.getSession('my_server')

    // List all available tools - always returns fresh data
    const tools = await session.listTools()

    for (const tool of tools) {
        console.log(`Tool: ${tool.name}`)
        console.log(`Description: ${tool.description}`)
        console.log(`Schema: ${JSON.stringify(tool.inputSchema)}`)
        console.log('---')
    }

    await client.closeAllSessions()
}

// Run the example
listTools().catch(console.error)
```

```typescript TypeScript
import { MCPClient } from 'mcp-use'

async function listTools() {
    // Initialize client with server configuration
    const config = {
        mcpServers: {
            // Your server definitions here
        }
    }
    const client = new MCPClient(config)

    // Connect to servers
    await client.createAllSessions()

    // Get a session for a specific server
    const session = client.getSession('my_server')

    // List all available tools - always returns fresh data
    const tools = await session.listTools()

    for (const tool of tools) {
        console.log(`Tool: ${tool.name}`)
        console.log(`Description: ${tool.description}`)
        console.log(`Schema: ${JSON.stringify(tool.inputSchema)}`)
        console.log('---')
    }

    await client.closeAllSessions()
}

// Run the example
listTools().catch(console.error)
```
</CodeGroup>

### Dynamic Tool Lists

<Info>
MCP servers can dynamically add, remove, or modify tools at runtime. When this happens, servers send a `ToolListChangedNotification` to inform clients that the tool list has changed.
</Info>

The `listTools()` method always fetches fresh data from the server, ensuring you have the most current information:

**Important:** Always use `await session.listTools()` instead of the deprecated `session.tools` property:

<CodeGroup>
```typescript TypeScript
// ✅ Recommended - always returns fresh data
const tools = await session.listTools()

// ⚠️ Deprecated - may return stale data
// const tools = session.tools
```

```typescript TypeScript
// ✅ Recommended - always returns fresh data
const tools = await session.listTools()

// ⚠️ Deprecated - may return stale data
// const tools = session.tools
```
</CodeGroup>

## Calling Tools

Tools are executed using the `call_tool` method:

<CodeGroup>
```typescript TypeScript
import { MCPClient } from 'mcp-use'

async function callToolExample() {
    const config = {
        mcpServers: {
            // Your server definitions here
        }
    }
    const client = new MCPClient(config)
    await client.createAllSessions()

    const session = client.getSession('filesystem_server')

    // Call a tool with arguments
    const result = await session.callTool(
        'read_file',
        {
            path: '/path/to/file.txt',
            encoding: 'utf-8'
        }
    )

    // Handle the result
    if (result.isError) {
        console.error(`Error: ${result.content}`)
    } else {
        console.log(`File content: ${result.content}`)
    }

    await client.closeAllSessions()
}

callToolExample().catch(console.error)
```

```typescript TypeScript
import { MCPClient } from 'mcp-use'

async function callToolExample() {
    const config = {
        mcpServers: {
            // Your server definitions here
        }
    }
    const client = new MCPClient(config)
    await client.createAllSessions()

    const session = client.getSession('filesystem_server')

    // Call a tool with arguments
    const result = await session.callTool(
        'read_file',
        {
            path: '/path/to/file.txt',
            encoding: 'utf-8'
        }
    )

    // Handle the result
    if (result.isError) {
        console.error(`Error: ${result.content}`)
    } else {
        console.log(`File content: ${result.content}`)
    }

    await client.closeAllSessions()
}

callToolExample().catch(console.error)
```
</CodeGroup>

## Timeout Configuration

<Tip>
The default timeout for tool calls is 60 seconds. For long-running operations like data processing or external API calls, you should configure appropriate timeout values.
</Tip>

Configure custom timeouts for tool execution:

<CodeGroup>
```typescript TypeScript
// Tool call with extended timeout
const result = await session.callTool('long_running_task', { data: '...' }, {
    timeout: 300000, // 5 minutes
})
```

```typescript TypeScript
// Tool call with progress-based timeout reset
// This allows the timeout to reset whenever the server sends a progress notification
const result = await session.callTool('sampling_task', { prompt: '...' }, {
    timeout: 60000, // 1 minute initial timeout
    resetTimeoutOnProgress: true // Reset timeout when progress is received
})
```
</CodeGroup>

Available options:
- **`timeout`**: Request timeout in milliseconds (default: 60000)
- **`maxTotalTimeout`**: Maximum total time in milliseconds, even with progress resets
- **`resetTimeoutOnProgress`**: If true, resets the timeout counter when a progress notification is received (default: false)
- **`signal`**: An `AbortSignal` to programmatically cancel the request

## Tool Results

Tool calls return a `CallToolResult` object with:
- `content`: The result data or error message
- `isError`: Boolean indicating success or failure
- Additional metadata about the execution

<CodeGroup>
```typescript TypeScript
// Example of handling tool results
const result = await session.callTool('search_web', { query: 'MCP protocol' })

if (result.isError) {
    console.error(`Tool execution failed: ${result.content}`)
} else {
    // Process successful result
    for (const item of result.content) {
        console.log(`Found: ${item}`)
    }
}
```

```typescript TypeScript
// Example of handling tool results
const result = await session.callTool('search_web', { query: 'MCP protocol' })

if (result.isError) {
    console.error(`Tool execution failed: ${result.content}`)
} else {
    // Process successful result
    for (const item of result.content) {
        console.log(`Found: ${item}`)
    }
}
```
</CodeGroup>

## Error Handling

Always handle potential errors when calling tools:

<CodeGroup>
```typescript TypeScript
try {
    const result = await session.callTool('risky_operation', { param: 'value' })
    if (result.isError) {
        console.error(`Tool reported error: ${result.content}`)
    } else {
        console.log(`Success: ${result.content}`)
    }
} catch (error) {
    console.error(`Connection or protocol error: ${error}`)
}
```

```typescript TypeScript
try {
    const result = await session.callTool('risky_operation', { param: 'value' })
    if (result.isError) {
        console.error(`Tool reported error: ${result.content}`)
    } else {
        console.log(`Success: ${result.content}`)
    }
} catch (error) {
    console.error(`Connection or protocol error: ${error}`)
}
```
</CodeGroup>
